﻿using System;
using System.Data;

using NORM.Common;

namespace NORM.SQLObject
{
    using NORM.DataBase;

    /// <summary>
    /// 生成器
    /// </summary>
    public class Generator
    {
        public static void BuildEntity(DataBase db, string name, string spacename, out string result, DataBaseSchema schema = DataBaseSchema.Table)
        {
            DataTable dt = db.GetDataBaseObject(name, schema);

            string entityType = string.Empty;
            switch (schema)
            {
                case DataBaseSchema.Table: entityType = "Table"; break;
                case DataBaseSchema.View: entityType = "View"; break;
                default: break;
            }

            StringPlus rvl = new StringPlus();
            rvl.Append("using System;").Append("\r\n").Append("\r\n");
            //rvl.Append("using NORM.Common;").Append("\r\n");
            rvl.Append("using NORM.Entity;").Append("\r\n").Append("\r\n");
            rvl.Append("namespace " + spacename + "").Append("\r\n");
            rvl.Append("{").Append("\r\n");
            rvl.Append("    ///名称：" + name + "").Append("\r\n");
            rvl.Append("    ///作者：wxdong").Append("\r\n");
            rvl.Append("    ///创建时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + " ").Append("\r\n");
            rvl.Append("    [Serializable]").Append("\r\n");
            rvl.Append("    [AtttribDescrib(\"" + entityType + "\")]").Append("\r\n");
            rvl.Append("    public class " + name + " : EntityBase").Append("\r\n");
            rvl.Append("    {").Append("\r\n");
            rvl.Append("        public " + name + "()").Append("\r\n");
            rvl.Append("        {").Append("\r\n");
            rvl.Append("            TableName = \"" + name + "\";").Append("\r\n");
            rvl.Append("            PrimaryKey.Add(\"$PrimaryKey$\");").Append("\r\n");
            rvl.Append("        }").Append("\r\n");
            rvl.Append("        #region Model").Append("\r\n");

            string PrimaryKey = string.Empty;
            foreach (DataRow dr in dt.Rows)
            {
                string column_name = dr["ColumnName"] + "";
                string column_type = dr["TypeName"] + "";
                string column_length = dr["Length"] + "";
                string column_describ = dr["Describ"] + "";
                string column_isnull = dr["CisNull"] + "";
                string column_identify = string.Empty;
                string column_attrdescrib = string.Empty;

                switch (column_type)
                {
                    case "char":
                    case "nchar":
                    case "varchar":
                    case "nvarchar":
                    case "text":
                    case "ntext":
                        column_type = "string";
                        break;
                    case "real":
                    case "money":
                    case "decimal":
                        column_type = "decimal";
                        break;
                    case "date":
                    case "smalldate":
                        column_type = "string";
                        column_attrdescrib = "Type::Sdt";
                        break;
                    case "datetime":
                    case "timestamp with time zone":
                        column_type = "DateTime";
                        break;
                    case "long":
                    case "integer":
                        column_type = "Int64";
                        break;
                    case "image":
                    case "byte[]":
                        column_type = "byte[]";
                        break;
                    case "int":
                    case "int16":
                    case "int32":
                        column_type = "int";
                        break;
                    case "double":
                        column_type = "double";
                        break;
                    case "float":
                        column_type = "float";
                        break;
                    case "guid":
                    case "uuid":
                        column_type = "Guid?";
                        break;
                    case "character":
                        column_type = "char";
                        break;
                    case "bit":
                    case "bit(1)":
                        column_attrdescrib = "Type::Bit";
                        column_type = "bool";
                        break;
                    case "bool":
                        column_type = "bool";
                        break;
                    default:
                        column_type = "string";
                        break;
                }

                if (column_isnull.Contains("pk"))
                {
                    PrimaryKey = column_name;
                }

                if ((column_isnull.Contains("identify") || column_isnull.Contains("pk")) && (column_type == "Int64" || column_type == "int"))
                {
                    column_identify = "[AtttribDescrib(\"Identify\")]";
                }

                //rvl.Append("        private " + column_type + " _" + column_name.ToLower() + ";").Append("\r\n");
                rvl.Append("        /// <summary>").Append("\r\n");
                rvl.Append("        /// " + column_describ + "").Append("\r\n");
                rvl.Append("        /// </summary>").Append("\r\n");
                if (!string.IsNullOrEmpty(column_identify))
                {
                    rvl.Append("        [AtttribDescrib(\"Identify\")]").Append("\r\n");
                }
                if (!string.IsNullOrEmpty(column_attrdescrib))
                {
                    rvl.Append("        [AtttribDescrib(\"" + column_attrdescrib + "\")]").Append("\r\n");
                }
                rvl.Append("        public " + column_type + " " + column_name + "").Append("\r\n");
                rvl.Append("        {").Append("\r\n");
                //rvl.Append("            get { return _" + column_name.ToLower() + "; }").Append("\r\n");
                //rvl.Append("            set { _" + column_name.ToLower() + " = value; }").Append("\r\n");
                rvl.Append("              get{ return getProperty<" + column_type + ">(\"" + column_name + "\");}");
                rvl.Append("              set{ setProperty(\"" + column_name + "\", value);}");
                rvl.Append("        }").Append("\r\n");

            }

            rvl.Append("        #endregion Model").Append("\r\n");
            rvl.Append("    }").Append("\r\n");
            rvl.Append("}").Append("\r\n");

            result = rvl.Value.Replace("$PrimaryKey$", PrimaryKey);

        }

    }
}
